package cn.zust.itcost.service.impl;

import cn.zust.itcost.service.BM25Service;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

@Slf4j
@Service
public class BM25ServiceImpl implements BM25Service {

    private Map<String, Integer> idf;

    public BM25ServiceImpl() {
        idf = new HashMap<>();
        idf.put("word", 10);//测试
        idf.put("words", 8);//测试

//        String input = "3苹果,3香蕉,3橙子,10水果,3经验,3人,5水果";
//
//        // 创建HashMap用于存储数字和名词对应关系
//        HashMap<String, Integer> idf = new HashMap<>();
//
//        // 按逗号分割句子
//        String[] items = input.split(",");
//        for (String item : items) {
//            // 提取数字和名词
//            String[] parts = item.split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)");
//            if (parts.length == 2) {
//                String fruit = parts[1];
//                int number = Integer.parseInt(parts[0]);
//                idf.put(fruit, number);
//            }
//        }
    }

    @Override
    //s1 查询的关键词。s2 文档内容。sAvg 平均文档长度，k1 和 b 是调节参数,k1 控制词频对得分影响的参数，b 控制文档长度对得分影响的参数。
    public double calculateBM25(String s1, String s2, double sAvg, double k1, double b) {
        double sim = 0;
        int lenD = s2.length();

        // 1. 分词
        String[] s1List = s1.split(",");
        String[] s2List = s2.split(",");

        // 2. 计算s1中每个词与s2的相关度得分并累加得s1与s2的相关度
        for (String w : s1List) {
            double idfW = idf.getOrDefault(w, 1);
            int fid = countWordFrequency(s2List, w);
            double score = calculateWordScore(idfW, fid, lenD, sAvg, k1, b);
            sim += score;
        }

        return sim;

    }

    private int countWordFrequency(String[] words, String target) {
        int count = 0;
        for (String word : words) {
            if (word.equals(target)) {
                count++;
            }
        }
        return count;
    }

    private double calculateWordScore(double idfW, int fid, int lenD, double sAvg, double k1, double b) {
        double ra = fid * (k1 + 1);
        double rb = fid + k1 * (1 - b + b * lenD / sAvg);
        return idfW * (ra / rb);
    }

    @Test
    public void testCalculateBM25() {
        String sinput ="10word,8words";
        BM25ServiceImpl bm25Service = new BM25ServiceImpl();
        String s1 = "word,words,word";
        String s2 = "word,words,word,words";//被比较对象
        double sAvg = 5.0;
        double k1 = 1.2;
        double b = 0.75;

        //相对比较
        double result = bm25Service.calculateBM25(s1, s2, sAvg, k1, b);
        //自比较
        double result2 = bm25Service.calculateBM25(s2, s2, sAvg, k1, b);

        //结果
        log.info(String.valueOf((result/result2)*100));
    }
}
